package net.lab1024.sa.admin.module.business.pdf.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * OCR性能监控工具
 * 跟踪识别效果，自动优化策略
 *
 * @Author 1024创新实验室
 */
@Slf4j
@Component
public class OcrPerformanceMonitor {

    // 存储页面识别结果和策略效果
    private final Map<String, PageOcrResult> pageResults = new ConcurrentHashMap<>();
    
    // 存储策略效果统计
    private final Map<String, StrategyPerformance> strategyStats = new ConcurrentHashMap<>();
    
    // 存储图像质量与策略的关联
    private final Map<String, QualityStrategyMapping> qualityMappings = new ConcurrentHashMap<>();

    /**
     * 记录页面OCR结果
     */
    public void recordPageResult(int pageNumber, String imageQuality, String strategy, 
                                String ocrResult, long processingTime, boolean success) {
        String pageKey = "page_" + pageNumber;
        
        PageOcrResult result = new PageOcrResult();
        result.setPageNumber(pageNumber);
        result.setImageQuality(imageQuality);
        result.setStrategy(strategy);
        result.setOcrResult(ocrResult);
        result.setProcessingTime(processingTime);
        result.setSuccess(success);
        result.setTimestamp(System.currentTimeMillis());
        
        // 分析OCR结果质量
        Map<String, Object> ocrAnalysis = analyzeOcrQuality(ocrResult);
        result.setOcrQuality((String) ocrAnalysis.get("quality"));
        result.setChineseCharCount((Integer) ocrAnalysis.get("chineseChars"));
        result.setResultLength((Integer) ocrAnalysis.get("textLength"));
        
        pageResults.put(pageKey, result);
        
        // 更新策略统计
        updateStrategyStats(strategy, result);
        
        // 更新质量映射
        updateQualityMapping(imageQuality, strategy, result);
        
        log.info("记录页面OCR结果: 页面={}, 质量={}, 策略={}, 成功率={}, 处理时间={}ms", 
                pageNumber, imageQuality, strategy, success, processingTime);
    }
    
    /**
     * 获取最佳策略建议
     */
    public String getBestStrategyForQuality(String imageQuality) {
        QualityStrategyMapping mapping = qualityMappings.get(imageQuality);
        if (mapping == null) {
            return "moderate"; // 默认策略
        }
        
        // 根据成功率选择最佳策略
        String bestStrategy = mapping.getStrategies().entrySet().stream()
                .max(Comparator.comparingDouble(entry -> entry.getValue().getSuccessRate()))
                .map(Map.Entry::getKey)
                .orElse("moderate");
        
        log.info("为图像质量 {} 推荐策略: {}", imageQuality, bestStrategy);
        return bestStrategy;
    }
    
    /**
     * 获取策略性能报告
     */
    public Map<String, Object> getStrategyPerformanceReport() {
        Map<String, Object> report = new HashMap<>();
        
        // 总体统计
        int totalPages = pageResults.size();
        int successfulPages = (int) pageResults.values().stream().filter(PageOcrResult::isSuccess).count();
        double overallSuccessRate = totalPages > 0 ? (double) successfulPages / totalPages : 0.0;
        
        report.put("totalPages", totalPages);
        report.put("successfulPages", successfulPages);
        report.put("overallSuccessRate", overallSuccessRate);
        
        // 策略统计
        Map<String, Object> strategyReport = new HashMap<>();
        for (Map.Entry<String, StrategyPerformance> entry : strategyStats.entrySet()) {
            StrategyPerformance perf = entry.getValue();
            Map<String, Object> perfData = new HashMap<>();
            perfData.put("totalPages", perf.getTotalPages());
            perfData.put("successfulPages", perf.getSuccessfulPages());
            perfData.put("successRate", perf.getSuccessRate());
            perfData.put("avgProcessingTime", perf.getAverageProcessingTime());
            perfData.put("avgChineseChars", perf.getAverageChineseChars());
            perfData.put("avgResultLength", perf.getAverageResultLength());
            
            strategyReport.put(entry.getKey(), perfData);
        }
        report.put("strategyStats", strategyReport);
        
        // 质量映射统计
        Map<String, Object> qualityReport = new HashMap<>();
        for (Map.Entry<String, QualityStrategyMapping> entry : qualityMappings.entrySet()) {
            QualityStrategyMapping mapping = entry.getValue();
            Map<String, Object> mappingData = new HashMap<>();
            mappingData.put("totalPages", mapping.getTotalPages());
            mappingData.put("bestStrategy", mapping.getBestStrategy());
            mappingData.put("bestSuccessRate", mapping.getBestSuccessRate());
            
            qualityReport.put(entry.getKey(), mappingData);
        }
        report.put("qualityMappings", qualityReport);
        
        return report;
    }
    
    /**
     * 获取优化建议
     */
    public List<String> getOptimizationSuggestions() {
        List<String> suggestions = new ArrayList<>();
        
        // 分析整体性能
        double overallSuccessRate = pageResults.values().stream()
                .mapToDouble(result -> result.isSuccess() ? 1.0 : 0.0)
                .average()
                .orElse(0.0);
        
        if (overallSuccessRate < 0.7) {
            suggestions.add("整体识别成功率较低，建议检查图像质量和语言包配置");
        }
        
        // 分析策略效果
        for (Map.Entry<String, StrategyPerformance> entry : strategyStats.entrySet()) {
            StrategyPerformance perf = entry.getValue();
            if (perf.getSuccessRate() < 0.5) {
                suggestions.add(String.format("策略 '%s' 成功率较低 (%.1f%%)，建议调整参数", 
                        entry.getKey(), perf.getSuccessRate() * 100));
            }
            
            if (perf.getAverageProcessingTime() > 5000) {
                suggestions.add(String.format("策略 '%s' 处理时间较长 (%.0fms)，建议优化性能", 
                        entry.getKey(), perf.getAverageProcessingTime()));
            }
        }
        
        // 分析质量映射
        for (Map.Entry<String, QualityStrategyMapping> entry : qualityMappings.entrySet()) {
            QualityStrategyMapping mapping = entry.getValue();
            if (mapping.getBestSuccessRate() < 0.6) {
                suggestions.add(String.format("图像质量 '%s' 的最佳策略成功率较低 (%.1f%%)，建议开发新的优化策略", 
                        entry.getKey(), mapping.getBestSuccessRate() * 100));
            }
        }
        
        if (suggestions.isEmpty()) {
            suggestions.add("当前OCR性能良好，无需特别优化");
        }
        
        return suggestions;
    }
    
    /**
     * 更新策略统计
     */
    private void updateStrategyStats(String strategy, PageOcrResult result) {
        StrategyPerformance perf = strategyStats.computeIfAbsent(strategy, k -> new StrategyPerformance());
        perf.setStrategy(strategy);
        perf.setTotalPages(perf.getTotalPages() + 1);
        
        if (result.isSuccess()) {
            perf.setSuccessfulPages(perf.getSuccessfulPages() + 1);
        }
        
        // 更新平均处理时间
        long totalTime = perf.getTotalProcessingTime() + result.getProcessingTime();
        perf.setTotalProcessingTime(totalTime);
        perf.setAverageProcessingTime((double) totalTime / perf.getTotalPages());
        
        // 更新平均中文字符数
        long totalChineseChars = perf.getTotalChineseChars() + result.getChineseCharCount();
        perf.setTotalChineseChars(totalChineseChars);
        perf.setAverageChineseChars((double) totalChineseChars / perf.getTotalPages());
        
        // 更新平均结果长度
        long totalLength = perf.getTotalResultLength() + result.getResultLength();
        perf.setTotalResultLength(totalLength);
        perf.setAverageResultLength((double) totalLength / perf.getTotalPages());
        
        // 计算成功率
        perf.setSuccessRate((double) perf.getSuccessfulPages() / perf.getTotalPages());
    }
    
    /**
     * 更新质量映射
     */
    private void updateQualityMapping(String imageQuality, String strategy, PageOcrResult result) {
        QualityStrategyMapping mapping = qualityMappings.computeIfAbsent(imageQuality, k -> new QualityStrategyMapping());
        mapping.setImageQuality(imageQuality);
        mapping.setTotalPages(mapping.getTotalPages() + 1);
        
        // 更新策略统计
        StrategyPerformance perf = mapping.getStrategies().computeIfAbsent(strategy, k -> new StrategyPerformance());
        perf.setStrategy(strategy);
        perf.setTotalPages(perf.getTotalPages() + 1);
        
        if (result.isSuccess()) {
            perf.setSuccessfulPages(perf.getSuccessfulPages() + 1);
        }
        
        perf.setSuccessRate((double) perf.getSuccessfulPages() / perf.getTotalPages());
        
        // 更新最佳策略
        String bestStrategy = mapping.getStrategies().entrySet().stream()
                .max(Comparator.comparingDouble(entry -> entry.getValue().getSuccessRate()))
                .map(Map.Entry::getKey)
                .orElse(strategy);
        
        mapping.setBestStrategy(bestStrategy);
        mapping.setBestSuccessRate(mapping.getStrategies().get(bestStrategy).getSuccessRate());
    }
    
    /**
     * 分析OCR结果质量
     */
    private Map<String, Object> analyzeOcrQuality(String ocrText) {
        Map<String, Object> analysis = new HashMap<>();
        
        if (ocrText == null || ocrText.trim().isEmpty()) {
            analysis.put("quality", "失败");
            analysis.put("chineseChars", 0);
            analysis.put("textLength", 0);
            return analysis;
        }
        
        String trimmedText = ocrText.trim();
        int length = trimmedText.length();
        
        // 计算中文字符数量
        int chineseChars = 0;
        for (char c : trimmedText.toCharArray()) {
            if (c >= 0x4E00 && c <= 0x9FFF) {
                chineseChars++;
            }
        }
        
        analysis.put("textLength", length);
        analysis.put("chineseChars", chineseChars);
        
        // 评估质量
        if (length == 0) {
            analysis.put("quality", "失败");
        } else if (chineseChars > 0 && (double) chineseChars / length > 0.1) {
            analysis.put("quality", "优秀");
        } else if (length > 10) {
            analysis.put("quality", "良好");
        } else {
            analysis.put("quality", "一般");
        }
        
        return analysis;
    }
    
    /**
     * 页面OCR结果
     */
    public static class PageOcrResult {
        private int pageNumber;
        private String imageQuality;
        private String strategy;
        private String ocrResult;
        private long processingTime;
        private boolean success;
        private long timestamp;
        private String ocrQuality;
        private int chineseCharCount;
        private int resultLength;
        
        // Getters and Setters
        public int getPageNumber() { return pageNumber; }
        public void setPageNumber(int pageNumber) { this.pageNumber = pageNumber; }
        
        public String getImageQuality() { return imageQuality; }
        public void setImageQuality(String imageQuality) { this.imageQuality = imageQuality; }
        
        public String getStrategy() { return strategy; }
        public void setStrategy(String strategy) { this.strategy = strategy; }
        
        public String getOcrResult() { return ocrResult; }
        public void setOcrResult(String ocrResult) { this.ocrResult = ocrResult; }
        
        public long getProcessingTime() { return processingTime; }
        public void setProcessingTime(long processingTime) { this.processingTime = processingTime; }
        
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        
        public long getTimestamp() { return timestamp; }
        public void setTimestamp(long timestamp) { this.timestamp = timestamp; }
        
        public String getOcrQuality() { return ocrQuality; }
        public void setOcrQuality(String ocrQuality) { this.ocrQuality = ocrQuality; }
        
        public int getChineseCharCount() { return chineseCharCount; }
        public void setChineseCharCount(int chineseCharCount) { this.chineseCharCount = chineseCharCount; }
        
        public int getResultLength() { return resultLength; }
        public void setResultLength(int resultLength) { this.resultLength = resultLength; }
    }
    
    /**
     * 策略性能统计
     */
    public static class StrategyPerformance {
        private String strategy;
        private int totalPages;
        private int successfulPages;
        private double successRate;
        private long totalProcessingTime;
        private double averageProcessingTime;
        private long totalChineseChars;
        private double averageChineseChars;
        private long totalResultLength;
        private double averageResultLength;
        
        // Getters and Setters
        public String getStrategy() { return strategy; }
        public void setStrategy(String strategy) { this.strategy = strategy; }
        
        public int getTotalPages() { return totalPages; }
        public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
        
        public int getSuccessfulPages() { return successfulPages; }
        public void setSuccessfulPages(int successfulPages) { this.successfulPages = successfulPages; }
        
        public double getSuccessRate() { return successRate; }
        public void setSuccessRate(double successRate) { this.successRate = successRate; }
        
        public long getTotalProcessingTime() { return totalProcessingTime; }
        public void setTotalProcessingTime(long totalProcessingTime) { this.totalProcessingTime = totalProcessingTime; }
        
        public double getAverageProcessingTime() { return averageProcessingTime; }
        public void setAverageProcessingTime(double averageProcessingTime) { this.averageProcessingTime = averageProcessingTime; }
        
        public long getTotalChineseChars() { return totalChineseChars; }
        public void setTotalChineseChars(long totalChineseChars) { this.totalChineseChars = totalChineseChars; }
        
        public double getAverageChineseChars() { return averageChineseChars; }
        public void setAverageChineseChars(double averageChineseChars) { this.averageChineseChars = averageChineseChars; }
        
        public long getTotalResultLength() { return totalResultLength; }
        public void setTotalResultLength(long totalResultLength) { this.totalResultLength = totalResultLength; }
        
        public double getAverageResultLength() { return averageResultLength; }
        public void setAverageResultLength(double averageResultLength) { this.averageResultLength = averageResultLength; }
    }
    
    /**
     * 质量策略映射
     */
    public static class QualityStrategyMapping {
        private String imageQuality;
        private int totalPages;
        private Map<String, StrategyPerformance> strategies = new HashMap<>();
        private String bestStrategy;
        private double bestSuccessRate;
        
        // Getters and Setters
        public String getImageQuality() { return imageQuality; }
        public void setImageQuality(String imageQuality) { this.imageQuality = imageQuality; }
        
        public int getTotalPages() { return totalPages; }
        public void setTotalPages(int totalPages) { this.totalPages = totalPages; }
        
        public Map<String, StrategyPerformance> getStrategies() { return strategies; }
        public void setStrategies(Map<String, StrategyPerformance> strategies) { this.strategies = strategies; }
        
        public String getBestStrategy() { return bestStrategy; }
        public void setBestStrategy(String bestStrategy) { this.bestStrategy = bestStrategy; }
        
        public double getBestSuccessRate() { return bestSuccessRate; }
        public void setBestSuccessRate(double bestSuccessRate) { this.bestSuccessRate = bestSuccessRate; }
    }
} 